package msu.ml.data.level2;

import java.io.*;

public class VolumeReader
{
   private BlockReader br;

   public VolumeReader(BlockReader br)
   {
      this.br = br;
   }

   public void close()
   {
      if(br != null)
         br.close();
   }

	public Header getHeader()
	{
		return br.getHeader();
	}

   public Volume readVolume()
   {
      Volume volume = new Volume();

      int scans = 1;

      IPacket packet = readToBeginningOfScan();
      IVolumeCoveragePattern vcp = VolumeCoveragePatternFactory.createVolumeCoveragePattern(packet.getVolumeCoveragePattern());
      float [] angles = vcp.getAngles();
      for(int i = 0; i < angles.length; i++)
      {
         Sweep sweep = new Sweep();
         int indexes = vcp.getIndexesForAngle(angles[i]).size();
         for(int j = 0; j < indexes; j++)
         {
            Scan scan = new Scan(j);
            while(!isEndOfScan(packet))
            {
               scan.addRay(new Ray(packet));
               packet = readPacket();
            }
            scan.addRay(new Ray(packet));
            scan.setVolumeCoveragePattern(vcp);
            scan.sortRays();
            sweep.addScan(scan);
            if(!isEndOfVolume(packet))
               packet = readPacket();
         }
         volume.addSweep(sweep);
      }

      volume.setTime(getHeader().time, getHeader().date);

      return volume;
   }

   private boolean isBeginningOfScan(IPacket p)
   {
      return p.getRayStatus() == 0 || p.getRayStatus() == 3;
   }

   private boolean isEndOfScan(IPacket p)
   {
      return p.getRayStatus() == 2 || p.getRayStatus() == 4;
   }

   private boolean isEndOfVolume(IPacket p)
   {
      return p.getRayStatus() == 4;
   }

   private IPacket readToBeginningOfScan()
   {
      IPacket p = readPacket();
      //0 = Start of new Elevation, 3 = Beginning of Volume
      while(p.getRayStatus() != 0 && p.getRayStatus() != 3)
         p = readPacket();
      return p;
   }

   private IPacket readPacket()
   {
      IPacket p = br.read();
      while(p == null || !p.isRadialData())
         p = br.read();

      System.out.flush();

      return p;
   }
}
